﻿#include "stdafx.h"
#include "AsioTimerTest.h"

#include <iostream>
using namespace std;

#define BOOST_ASIO_DISABLE_STD_CHRONO
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
//#include <boost/asio/use_future.hpp>
using namespace boost::asio;
using namespace boost::system;


#include <boost/chrono.hpp>
using namespace boost::chrono;
seconds operator"" _s(unsigned long long n)
{
	return seconds(n);
}

milliseconds operator""_ms(unsigned long long n)
{
	return milliseconds(n);
}

//////////////////////////////////////////
void TimerCase1()
{
	io_service io;

	steady_timer t(io, 500_ms);
	cout << t.expires_at() << endl;
	cout << t.expires_from_now() << endl;

	t.wait();
	cout << "hello asio1" << endl;
}

//////////////////////////////////////////

void TimerCase2()
{
	// 运行会崩溃，原因未知，定义BOOST_ASIO_ENABLE_HANDLER_TRACKING则不崩溃，原因未知
	io_service io;

	steady_timer t(io, 500_ms);

	t.async_wait(
		[](const boost::system::error_code& ec) {
		cout << "hello asio2" << endl;
	});

	io.run();
}

//////////////////////////////////////////
class timer_with_func
{
	typedef timer_with_func this_type;
private:
	int m_count = 0;		// 计数器成员变量
	int m_count_max = 0;	// 计数器上限
	function<void()> m_f;	// function对象
	steady_timer m_t;		// asio定时器对象
public:
	template<typename F>
	timer_with_func(io_service& io, int x, F func) :
		m_count_max(x),
		m_f(func),
		m_t(io, 200_ms)
	{
		init();
	}

private:
	typedef void(handler_type)(const boost::system::error_code&);
	function<handler_type> m_handler =
		[&](const boost::system::error_code&)
	{
		if (m_count++ >= m_count_max)
		{
			return;
		}
		m_f();

		m_t.expires_from_now(200_ms);
		m_t.async_wait(m_handler);
	};

	void init()
	{
		// lambda方式
		m_t.async_wait(m_handler);

		// bind方式
		//m_t.async_wait(bind(
		//        &this_type::handler, this,
		//        boost::asio::placeholders::error));
		        //_1));
	}

	void handler(const boost::system::error_code&)
	{
		if (m_count++ >= m_count_max)
		{
			return;
		}

		m_f();

		m_t.expires_from_now(200_ms);

		m_t.async_wait(bind(
			&this_type::handler, this,
			boost::asio::placeholders::error));
	}
};

void TimerCase3()
{
	io_service io;

	timer_with_func t1(io, 5,
		[]{cout << "hello timer1" << endl; });

	//timer_with_func t2(io, 5,
	//    []{cout << "hello timer2"<<endl;});

	io.run();
}

//////////////////////////////////////////

void AsioTimerTest()
{
	// 异步定时器运行会崩溃，原因未知，定义BOOST_ASIO_ENABLE_HANDLER_TRACKING则不崩溃，原因未知

	//TimerCase1();
	//TimerCase2();
	TimerCase3();
}
